from datetime import datetime
import requests
from RedisTool import redis_util
import schedule
import time
import logging
import signal
import sys

"""
大乐透： 每周一、三、六 21：25开奖

排列五： 每日 21：25开奖

排列三： 每日 21：25开奖

七星彩： 每周二、五、日 21：25开奖
"""


PAGE_SIZE = 1
BASE_URL = 'https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry?gameNo={game_no}&provinceId=0&pageSize={page_size}&isVerify=1&pageNo=1'
def get_url(page_size, game_no):
    """生成请求URL"""
    return BASE_URL.format(page_size=page_size, game_no=game_no)


def get_result_json(game_no):
    """获取并解析JSON数据"""
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
            'Accept-Language': 'en-US,en;q=0.5',
            'Referer': 'https://www.baidu.com/'  # 根据实际网站填写
        }
        url = get_url(PAGE_SIZE, game_no)  # 修复参数传递错误
        response = requests.get(url, timeout=10, headers=headers)
        response.raise_for_status()  # 抛出HTTP错误状态码

        data = response.json()
        # 检查返回结果是否存在
        if not data or 'value' not in data or not data['value']:
            raise ValueError(f"未获取到游戏{game_no}的有效数据")

        # 返回第一个结果（最近的一期）
        return data['value']['list'][0]

    except requests.exceptions.RequestException as e:
        raise ConnectionError(f"网络请求错误: {str(e)}")
    except (KeyError, IndexError) as e:
        raise ValueError(f"数据解析错误: {str(e)}")


def get_dlt_result():
    """获取大乐透结果"""
    try:
        dlt_info = get_result_json('85')
        draw_result = dlt_info.get('lotteryDrawResult').split(' ')
        return {
            'dlt_code': dlt_info.get('lotteryDrawNum'),
            'dlt_front_info': draw_result[:5],
            'dlt_back_info': draw_result[-2:] if len(draw_result) >= 2 else []
        }
    except Exception as e:
        raise ValueError(f"获取大乐透据失败: {str(e)}")


def get_pl3_result():
    """获取排列3结果"""
    try:
        pl3_info = get_result_json('35')
        return {
            'pl3_code': pl3_info.get('lotteryDrawNum'),
            'pl3_info': pl3_info.get('lotteryDrawResult', '').split(' ')
        }
    except Exception as e:
        raise ValueError(f"获取排列3数据失败: {str(e)}")

def get_pl5_result():
    """获取排列5结果"""
    try:
        pl5_info = get_result_json('350133')
        return {
            'pl5_code': pl5_info.get('lotteryDrawNum'),
            'pl5_info': pl5_info.get('lotteryDrawResult', '').split(' ')
        }
    except Exception as e:
        raise ValueError(f"获取排列5数据失败: {str(e)}")



def get_result():
    """整合所有结果"""
    return {
        **get_dlt_result(),
        **get_pl3_result(),
        **get_pl5_result()
    }

def save_ticai_lottery_data(data, date_key=None):
    """
    将体彩数据存入Redis，使用日期作为key

    :param data: 体彩数据字典
    :param date_key: 自定义日期key，默认为当前日期
    :return: 存储是否成功
    """
    # 如果未指定日期key，使用当前日期作为key，格式为YYYY-MM-DD
    if not date_key:
        today = datetime.today()
        date_key = today.strftime("%Y%m%d")

    # 为key添加前缀，方便后续查询
    redis_key = f"ticai_lottery_data:{date_key}"

    try:
        # 将数据存入Redis哈希表
        # 需要将列表转换为字符串存储，这里使用逗号分隔
        formatted_data = {}
        for key, value in data.items():
            if isinstance(value, list):
                # 列表类型用逗号连接成字符串
                formatted_data[key] = ",".join(value)
            else:
                formatted_data[key] = value

        # 存储数据，设置过期时间为1天（86400秒）
        result = redis_util.hmset(redis_key, formatted_data, expire_seconds=86400)

        if result:
            print(f"成功将体彩数据存入Redis，key: {redis_key}")
            return True
        else:
            print(f"存储体彩数据失败，key: {redis_key}")
            return False

    except Exception as e:
        print(f"存储体彩数据时发生错误: {str(e)}")
        return False


# 定时任务包装函数 - 关键修复
def job_wrapper():
    """包装定时任务，确保能被schedule正确调用"""
    try:
        save_ticai_lottery_data()
    except Exception as e:
        logger.error(f"定时任务执行失败: {str(e)}", exc_info=True)

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler("ticai_lottery_scheduler.log"),  # 日志写入文件
        logging.StreamHandler()  # 同时在控制台输出
    ]
)
logger = logging.getLogger(__name__)
# 程序运行状态
is_running = True


def signal_handler(sig, frame):
    """处理程序中断信号"""
    global is_running
    logger.info("收到中断信号，准备退出程序...")
    is_running = False
    sys.exit(0)

def ticai_run_scheduler():
    """启动调度器，每天固定时间执行任务"""
    global is_running
    #  使用包装函数job_wrapper，而非直接调用save_lottery_data(get_result())
    schedule.every().day.at("21:25").do(job_wrapper)
    schedule.every().day.at("21:26").do(job_wrapper)
    schedule.every().day.at("21:27").do(job_wrapper)
    schedule.every().day.at("21:30").do(job_wrapper)
    logger.info("已设置体彩定时任务")
    # 运行调度器
    logger.info("调度器开始运行，等待任务执行...")
    while is_running:
        schedule.run_pending()
        time.sleep(1)

    logger.info("调度器已停止")

if __name__ == "__main__":
    # 注册信号处理器，处理程序中断
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    try:
        # 启动调度器
        ticai_run_scheduler()
    except Exception as e:
        logger.critical(f"程序运行出错: {str(e)}", exc_info=True)
        sys.exit(1)